'''
Description: 
Author: Zilu
Date: 2021-11-12 19:35:16
Version: 
LastEditTime: 2021-11-12 21:46:56
LastEditors: Zilu
'''

# HTML 是 XML 的子集，可以用HTMLParser方法解析
from html.parser import HTMLParser
from html.entities import name2codepoint

class MyHTMLParser(HTMLParser):
    def handle_starttag(self, tag: str, attrs: list) -> None:
        print('<%s>' % tag)

    def handle_endtag(self, tag: str) -> None:
        print('</%s>' % tag)

    def handle_startendtag(self, tag: str, attrs: list) -> None:
        print('<%s/>' % tag)

    def handle_data(self, data) -> None:
        print(data)

    def handle_comment(self, data) -> None:
        print('<!--', data, '-->')

    def handle_entityref(self, name) -> None:
        print('&%s;' % name)

    def handle_charref(self, name) -> None:
        print('&#%s;' % name)

parser = MyHTMLParser()
parser.feed('''<html>
<head></head>
<body>
<!-- test html parser -->
    <p>Some <a href=\"#\">html</a> HTML&nbsp;tutorial...<br>END</p>
</body></html>''')

# 特殊字符有两种，一种是英文表示的&nbsp;，一种是数字表示的&#1234;，
# 这两种字符都可以通过Parser解析出来

# 练习:
# 找一个网页，例如https://www.python.org/events/python-events/，
# 用浏览器查看源码并复制，然后尝试解析一下HTML，输出Python官网发布的会议时间、名称和地点。
from html.parser import HTMLParser
from urllib import request

class MyHTMLParser(HTMLParser):
    def __init__(self, *, convert_charrefs: bool = ...) -> None:
        super().__init__(convert_charrefs=convert_charrefs)
        self.events = {'name':[], 'time':[], 'location':[]}
        self.__parsedata = ''

    def handle_starttag(self, tag: str, attrs: list[tuple[str, str or None]]) -> None:
        if ('class', 'event-title') in attrs:
            self.__parsedata = 'name'
        if tag == 'time' or ('class', 'datetime') in attrs:
            self.__parsedata = 'time'
        if ('class', 'event-location') in attrs:
            self.__parsedata = 'location'

    def handle_data(self, data: str) -> None:
        if self.__parsedata == 'name':
            self.events['name'].append(data)
        if self.__parsedata == 'time':
            self.events['time'].append(data)
        if self.__parsedata == 'location':
            # 有一个event没有location的data怎么处理
            if len(self.events['location'])+1 < len(self.events['name']):
                self.events['location'].append('')
            self.events['location'].append(data)

    def handle_endtag(self, tag: str) -> None:
        self.__parsedata = ''

def getData(url):
    # 模拟浏览器报头
    headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36 Edg/95.0.1020.44'}
    req = request.Request(url, headers = headers)
    with request.urlopen(req) as f:
        data = f.read()
        print(f'Status: {f.status} {f.reason}')
        print()
    return data.decode('utf-8')

parser = MyHTMLParser()
URL = 'https://www.python.org/events/python-events'
data = getData(URL)
parser.feed(data)

for i in range(len(parser.events['name'])):
    print(''.join(['会议名称：', parser.events['name'][i], '\n', 
                '会议地点：', parser.events['time'][2 * i], ' ', parser.events['time'][2 * i + 1], '\n', 
                '会议名称：', parser.events['location'][i], '\n']))
    print()

    


